(*
   Copyright (c) 2021-2025 Semgrep Inc.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   version 2.1 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
   LICENSE for more details.
*)
(* deprecated: this is used by Semgrep.dump_v_format to expose the AST to
 * Semgrep playground!
 * Use AST_generic.show_any instead.
 *)
open Fpath_.Operators
open Tok
open AST_generic

let vof_filename v = OCaml.vof_string v

let vof_token_location
    {
      Loc.str = v_str;
      pos =
        {
          bytepos = v_charpos;
          line = v_line;
          column = v_column;
          file = v_file;
          _;
        };
    } =
  let bnds = [] in
  let arg = vof_filename !!v_file in
  let bnd = ("file", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_int v_column in
  let bnd = ("column", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_int v_line in
  let bnd = ("line", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_int v_charpos in
  let bnd = ("bytepos", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_string v_str in
  let bnd = ("str", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

let vof_token_origin = function
  | OriginTok v1 ->
      let v1 = vof_token_location v1 in
      OCaml.VSum ("OriginTok", [ v1 ])
  | FakeTok (v1, opt) ->
      let v1 = OCaml.vof_string v1 in
      let opt =
        OCaml.vof_option
          (fun (p1, i) ->
            OCaml.VTuple [ vof_token_location p1; OCaml.vof_int i ])
          opt
      in
      OCaml.VSum ("FakeTok", [ v1; opt ])
  | Ab -> OCaml.VSum ("Ab", [])
  | ExpandedTok (v1, (v2, v3)) ->
      let v1 = vof_token_location v1 in
      let v2 = vof_token_location v2 in
      let v3 = OCaml.vof_int v3 in
      OCaml.VSum ("ExpandedTok", [ v1; v2; v3 ])

let vof_info v_token =
  let bnds = [] in
  let arg = vof_token_origin v_token in
  let bnd = ("token", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

let cmdline_flags_precision () =
  [
    ( "-full_token_info",
      Arg.Set Tok.pp_full_token_info,
      " print also token information in dumper" );
  ]

let vof_info_adjustable_precision x =
  (* old: [if !_current_precision.full_info then vof_info x].
   * However, full_info was true iff [-full_token_info] was set. *)
  if !Tok.pp_full_token_info then vof_info x
  (* old: [else if !_current_precision.token_info] then
   * However, this value was never reassigned from false!. *)
    else OCaml.VUnit

(* end of meta_parse_info.ml *)

(* When true, recurse into `Sym` svalues when printing. This is fairly likely to
 * blow up into large output, and may even lead to a stack overflow. Use only
 * for debugging, and use caution. *)
let debug_print_sym = false
let vof_tok v = vof_info_adjustable_precision v

(* generated by ocamltarzan with: camlp4o -o /tmp/yyy.ml -I pa/ pa_type_conv.cmo pa_vof.cmo  pr_o.cmo /tmp/xxx.ml  *)

let vof_wrap _of_a (v1, v2) =
  let v1 = _of_a v1 and v2 = vof_tok v2 in
  OCaml.VTuple [ v1; v2 ]

let vof_bracket of_a (t1, x, t2) =
  let v1 = vof_tok t1 in
  let v2 = vof_tok t2 in
  let v = of_a x in
  match v1 with
  | OCaml.VUnit -> v
  | __else__ -> OCaml.VTuple [ v1; v; v2 ]

let vof_ident v = vof_wrap OCaml.vof_string v
let vof_todo_kind v = vof_wrap OCaml.vof_string v
let vof_dotted_name v = OCaml.vof_list vof_ident v

let vof_module_name = function
  | FileName v1 ->
      let v1 = vof_wrap OCaml.vof_string v1 in
      OCaml.VSum ("FileName", [ v1 ])
  | DottedName v1 ->
      let v1 = vof_dotted_name v1 in
      OCaml.VSum ("DottedName", [ v1 ])

let vof_dotted_ident = vof_dotted_name

let rec vof_resolved_name (v1, v2) =
  let v1 = vof_resolved_name_kind v1 in
  let v2 = OCaml.vof_int (SId.to_int v2) in
  OCaml.VTuple [ v1; v2 ]

and vof_canonical_name v1 = OCaml.vof_list OCaml.vof_string v1

and vof_resolved_name_kind = function
  | LocalVar -> OCaml.VSum ("LocalVar", [])
  | Parameter -> OCaml.VSum ("Parameter", [])
  | EnclosedVar -> OCaml.VSum ("EnclosedVar", [])
  | Global -> OCaml.VSum ("Global", [])
  | ImportedEntity v1 ->
      let v1 = vof_canonical_name v1 in
      OCaml.VSum ("ImportedEntity", [ v1 ])
  | ImportedModule v1 ->
      let v1 = vof_canonical_name v1 in
      OCaml.VSum ("ImportedModule", [ v1 ])
  | Macro -> OCaml.VSum ("Macro", [])
  | EnumConstant -> OCaml.VSum ("EnumConstant", [])
  | TypeName -> OCaml.VSum ("TypeName", [])
  | GlobalName (v1, v2) ->
      let v1 = vof_canonical_name v1 in
      let v2 = OCaml.vof_list vof_canonical_name v2 in
      OCaml.VSum ("GlobalName", [ v1; v2 ])

let rec vof_qualifier = function
  | QDots v1 ->
      let v1 = OCaml.vof_list vof_ident_and_targs_opt v1 in
      OCaml.VSum ("QDots", [ v1 ])
  | QExpr (v1, v2) ->
      let v1 = vof_expr v1 in
      let v2 = vof_tok v2 in
      OCaml.VSum ("QExpr", [ v1; v2 ])

and vof_ident_and_targs_opt (v1, v2) =
  let v1 = vof_ident v1 in
  let v2 = OCaml.vof_option vof_type_arguments v2 in
  OCaml.VTuple [ v1; v2 ]

and vof_name_info
    {
      name_middle = v_name_qualifier;
      name_top = v_top;
      name_last = v1;
      name_info = v2;
    } =
  let bnds = [] in
  let arg = vof_id_info v2 in
  let bnd = ("name_info", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_qualifier v_name_qualifier in
  let bnd = ("name_middle", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_tok v_top in
  let bnd = ("name_top", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_ident_and_targs_opt v1 in
  let bnd = ("name_last", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_id_info
    {
      id_resolved = v_id_resolved;
      id_resolved_alternatives = v_id_resolved_alts;
      id_type = v_id_type;
      id_svalue = v3;
      id_flags;
      id_info_id;
    } =
  let bnds = [] in
  let arg = OCaml.vof_ref (OCaml.vof_option vof_svalue) v3 in
  let bnd = ("id_svalue", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_ref (OCaml.vof_option vof_type_) v_id_type in
  let bnd = ("id_type", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_ref (OCaml.vof_option vof_resolved_name) v_id_resolved in
  let bnd = ("id_resolved", arg) in
  let bnds = bnd :: bnds in
  let arg =
    OCaml.vof_ref
      (fun alts -> OCaml.vof_list vof_resolved_name alts)
      v_id_resolved_alts
  in
  let bnd = ("id_resolved_alternative", arg) in
  let bnds = bnd :: bnds in
  let arg =
    OCaml.vof_ref
      (fun id_flags -> OCaml.vof_int (IdFlags.to_int id_flags))
      id_flags
  in
  let bnd = ("id_flags", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_int (IdInfoId.to_int id_info_id) in
  let bnd = ("id_info_id", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_xml
    { xml_kind = v_xml_tag; xml_attrs = v_xml_attrs; xml_body = v_xml_body } =
  let bnds = [] in
  let arg = OCaml.vof_list vof_xml_body v_xml_body in
  let bnd = ("xml_body", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_xml_attribute v_xml_attrs in
  let bnd = ("xml_attrs", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_xmlkind v_xml_tag in
  let bnd = ("xml_tag", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_xmlkind = function
  | XmlClassic (v0, name, v2, v3) ->
      let v0 = vof_tok v0 in
      let name = vof_name name in
      let v2 = vof_tok v2 in
      let v3 = vof_tok v3 in
      OCaml.VSum ("XmlClassic", [ v0; name; v2; v3 ])
  | XmlSingleton (v0, name, v2) ->
      let v0 = vof_tok v0 in
      let name = vof_name name in
      let v2 = vof_tok v2 in
      OCaml.VSum ("XmlSingleton", [ v0; name; v2 ])
  | XmlFragment (v1, v2) ->
      let v1 = vof_tok v1 in
      let v2 = vof_tok v2 in
      OCaml.VSum ("XmlFragment", [ v1; v2 ])

and vof_xml_attribute = function
  | XmlAttr (v1, t, v2) ->
      let v1 = vof_ident v1 and t = vof_tok t and v2 = vof_xml_attr v2 in
      OCaml.VSum ("XmlAttr", [ v1; t; v2 ])
  | XmlAttrExpr v1 ->
      let v1 = vof_bracket vof_expr v1 in
      OCaml.VSum ("XmlAttrExpr", [ v1 ])
  | XmlEllipsis v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("XmlEllipsis", [ v1 ])

and vof_xml_attr v = vof_expr v

and vof_xml_body = function
  | XmlText v1 ->
      let v1 = vof_wrap OCaml.vof_string v1 in
      OCaml.VSum ("XmlText", [ v1 ])
  | XmlExpr v1 ->
      let v1 = vof_bracket (OCaml.vof_option vof_expr) v1 in
      OCaml.VSum ("XmlExpr", [ v1 ])
  | XmlXml v1 ->
      let v1 = vof_xml v1 in
      OCaml.VSum ("XmlXml", [ v1 ])

and vof_name = function
  | Id (v1, v2) ->
      let v1 = vof_ident v1 and v2 = vof_id_info v2 in
      OCaml.VSum ("Id", [ v1; v2 ])
  | IdQualified v1 ->
      let v1 = vof_name_info v1 in
      OCaml.VSum ("IdQualified", [ v1 ])
  | IdSpecial (v1, v2) ->
      let v1 = vof_wrap vof_special_ident v1 in
      let v2 = vof_id_info v2 in
      OCaml.VSum ("IdSpecial", [ v1; v2 ])

and vof_expr e =
  (* TODO: also dump e_id? *)
  match e.e with
  | LocalImportAll (v1, v2, v3) ->
      let v1 = vof_module_name v1 in
      let v2 = vof_tok v2 in
      let v3 = vof_expr v3 in
      OCaml.VSum ("LocalImportAll", [ v1; v2; v3 ])
  | DotAccessEllipsis (v1, v2) ->
      let v1 = vof_expr v1 in
      let v2 = vof_tok v2 in
      OCaml.VSum ("DotAccessEllipsis", [ v1; v2 ])
  | DisjExpr (v1, v2) ->
      let v1 = vof_expr v1 in
      let v2 = vof_expr v2 in
      OCaml.VSum ("DisjExpr", [ v1; v2 ])
  | Xml v1 ->
      let v1 = vof_xml v1 in
      OCaml.VSum ("Xml", [ v1 ])
  | L v1 ->
      let v1 = vof_literal v1 in
      OCaml.VSum ("L", [ v1 ])
  | Container (v1, v2) ->
      let v1 = vof_container_operator v1
      and v2 = vof_bracket (OCaml.vof_list vof_expr) v2 in
      OCaml.VSum ("Container", [ v1; v2 ])
  | Comprehension (v1, v2) ->
      let v1 = vof_container_operator v1
      and v2 = vof_bracket vof_comprehension v2 in
      OCaml.VSum ("Comprehension", [ v1; v2 ])
  | Record v1 ->
      let v1 = vof_bracket (OCaml.vof_list vof_field) v1 in
      OCaml.VSum ("Record", [ v1 ])
  | Constructor (v1, v2) ->
      let v1 = vof_name v1 and v2 = vof_bracket (OCaml.vof_list vof_expr) v2 in
      OCaml.VSum ("Constructor", [ v1; v2 ])
  | RegexpTemplate (v1, v2) ->
      let v1 = vof_bracket vof_expr v1 in
      let v2 = OCaml.vof_option (vof_wrap OCaml.vof_string) v2 in
      OCaml.VSum ("RegexpTemplate", [ v1; v2 ])
  | Lambda v1 ->
      let v1 = vof_function_definition v1 in
      OCaml.VSum ("Lambda", [ v1 ])
  | AnonClass v1 ->
      let v1 = vof_class_definition v1 in
      OCaml.VSum ("AnonClass", [ v1 ])
  | N v1 ->
      let v1 = vof_name v1 in
      OCaml.VSum ("N", [ v1 ])
  | Special v1 ->
      let v1 = vof_wrap vof_special v1 in
      OCaml.VSum ("Special", [ v1 ])
  | Call (v1, v2) ->
      let v1 = vof_expr v1 and v2 = vof_arguments v2 in
      OCaml.VSum ("Call", [ v1; v2 ])
  | New (v0, v1, v2, v3) ->
      let v0 = vof_tok v0 in
      let v1 = vof_type_ v1 and v2 = vof_id_info v2 and v3 = vof_arguments v3 in
      OCaml.VSum ("New", [ v0; v1; v2; v3 ])
  | Assign (v1, v2, v3) ->
      let v1 = vof_expr v1 and v2 = vof_tok v2 and v3 = vof_expr v3 in
      OCaml.VSum ("Assign", [ v1; v2; v3 ])
  | AssignOp (v1, v2, v3) ->
      let v1 = vof_expr v1
      and v2 = vof_wrap vof_arithmetic_operator v2
      and v3 = vof_expr v3 in
      OCaml.VSum ("AssignOp", [ v1; v2; v3 ])
  | LetPattern (v1, v2) ->
      let v1 = vof_pattern v1 and v2 = vof_expr v2 in
      OCaml.VSum ("LetPattern", [ v1; v2 ])
  | DotAccess (v1, t, v2) ->
      let v1 = vof_expr v1 and t = vof_tok t and v2 = vof_field_name v2 in
      OCaml.VSum ("DotAccess", [ v1; t; v2 ])
  | ArrayAccess (v1, v2) ->
      let v1 = vof_expr v1 and v2 = vof_bracket vof_expr v2 in
      OCaml.VSum ("ArrayAccess", [ v1; v2 ])
  | SliceAccess (v1, v2) ->
      let f = OCaml.vof_option vof_expr in
      let v1 = vof_expr v1 and v2 = vof_bracket (OCaml.vof_all3 f f f) v2 in
      OCaml.VSum ("SliceAccess", [ v1; v2 ])
  | Conditional (v1, v2, v3) ->
      let v1 = vof_expr v1 and v2 = vof_expr v2 and v3 = vof_expr v3 in
      OCaml.VSum ("Conditional", [ v1; v2; v3 ])
  | Yield (t, v1, v2) ->
      let t = vof_tok t in
      let v1 = OCaml.vof_option vof_expr v1 and v2 = OCaml.vof_bool v2 in
      OCaml.VSum ("Yield", [ t; v1; v2 ])
  | Await (t, v1) ->
      let t = vof_tok t in
      let v1 = vof_expr v1 in
      OCaml.VSum ("Await", [ t; v1 ])
  | Cast (v1, t, v2) ->
      let v1 = vof_type_ v1 and t = vof_tok t and v2 = vof_expr v2 in
      OCaml.VSum ("Cast", [ v1; t; v2 ])
  | Seq v1 ->
      let v1 = OCaml.vof_list vof_expr v1 in
      OCaml.VSum ("Seq", [ v1 ])
  | Ref (t, v1) ->
      let t = vof_tok t in
      let v1 = vof_expr v1 in
      OCaml.VSum ("Ref", [ t; v1 ])
  | DeRef (t, v1) ->
      let t = vof_tok t in
      let v1 = vof_expr v1 in
      OCaml.VSum ("DeRef", [ t; v1 ])
  | Alias (alias, v1) ->
      let alias = vof_wrap OCaml.vof_string alias in
      let v1 = vof_expr v1 in
      OCaml.VSum ("Alias", [ alias; v1 ])
  | Ellipsis v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("Ellipsis", [ v1 ])
  | DeepEllipsis v1 ->
      let v1 = vof_bracket vof_expr v1 in
      OCaml.VSum ("DeepEllipsis", [ v1 ])
  | TypedMetavar (v1, v2, v3) ->
      let v1 = vof_ident v1 and v2 = vof_tok v2 and v3 = vof_type_ v3 in
      OCaml.VSum ("TypedMetavar", [ v1; v2; v3 ])
  | StmtExpr v1 ->
      let v1 = vof_stmt v1 in
      OCaml.VSum ("StmtExpr", [ v1 ])
  | OtherExpr (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherExpr", [ v1; v2 ])
  | RawExpr x ->
      let x = vof_raw_tree x in
      OCaml.VSum ("RawExpr", [ x ])

and vof_field_name = function
  | FN v1 ->
      let v1 = vof_name v1 in
      OCaml.VSum ("FN", [ v1 ])
  | FDynamic v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("FDynamic", [ v1 ])

and vof_entity_name = function
  | EN v1 ->
      let v1 = vof_name v1 in
      OCaml.VSum ("EN", [ v1 ])
  | EDynamic v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("EDynamic", [ v1 ])
  | EPattern v1 ->
      let v1 = vof_pattern v1 in
      OCaml.VSum ("EPattern", [ v1 ])
  | OtherEntity (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherEntity", [ v1; v2 ])

and vof_literal = function
  | Unit v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("Unit", [ v1 ])
  | Bool v1 ->
      let v1 = vof_wrap OCaml.vof_bool v1 in
      OCaml.VSum ("Bool", [ v1 ])
  | Int (opt, tk) ->
      let v1 = vof_wrap (OCaml.vof_option OCaml.vof_int64) (opt, tk) in
      OCaml.VSum ("Int", [ v1 ])
  | Float v1 ->
      let v1 = vof_wrap (OCaml.vof_option OCaml.vof_float) v1 in
      OCaml.VSum ("Float", [ v1 ])
  | Imag v1 ->
      let v1 = vof_wrap OCaml.vof_string v1 in
      OCaml.VSum ("Imag", [ v1 ])
  | Ratio v1 ->
      let v1 = vof_wrap OCaml.vof_string v1 in
      OCaml.VSum ("Ratio", [ v1 ])
  | Atom (v0, v1) ->
      let v0 = vof_tok v0 in
      let v1 = vof_wrap OCaml.vof_string v1 in
      OCaml.VSum ("Atom", [ v0; v1 ])
  | Char v1 ->
      let v1 = vof_wrap OCaml.vof_string v1 in
      OCaml.VSum ("Char", [ v1 ])
  | String v1 ->
      let v1 = vof_bracket (vof_wrap OCaml.vof_string) v1 in
      OCaml.VSum ("String", [ v1 ])
  | Regexp (v1, v2) ->
      let v1 = vof_bracket (vof_wrap OCaml.vof_string) v1 in
      let v2 = OCaml.vof_option (vof_wrap OCaml.vof_string) v2 in
      OCaml.VSum ("Regexp", [ v1; v2 ])
  | Null v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("Null", [ v1 ])
  | Undefined v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("Undefined", [ v1 ])

and vof_const_type = function
  | Cbool -> OCaml.VSum ("Cbool", [])
  | Cint -> OCaml.VSum ("Cint", [])
  | Cstr -> OCaml.VSum ("Cstr", [])
  | Cany -> OCaml.VSum ("Cany", [])

and vof_svalue = function
  | Lit v1 ->
      let v1 = vof_literal v1 in
      OCaml.VSum ("Lit", [ v1 ])
  | Cst v1 ->
      let v1 = vof_const_type v1 in
      OCaml.VSum ("Cst", [ v1 ])
  | Sym v1 -> vof_sym v1
  | NotCst -> OCaml.VSum ("NotCst", [])

and vof_sym v1 =
  (* Do NOT go into symbolic values in production, see "CAREFUL" note in
   * AST_generic.svalue. *)
  let lst =
    if debug_print_sym then
      let v1 = vof_expr v1 in
      [ v1 ]
    else []
  in
  OCaml.VSum ("Sym", lst)

and vof_container_operator = function
  | Array -> OCaml.VSum ("Array", [])
  | List -> OCaml.VSum ("List", [])
  | Set -> OCaml.VSum ("Set", [])
  | Dict -> OCaml.VSum ("Dict", [])
  | Tuple -> OCaml.VSum ("Tuple", [])

and vof_comprehension (v1, v2) =
  let v1 = vof_expr v1 in
  let v2 = OCaml.vof_list vof_for_or_if_comp v2 in
  OCaml.VTuple [ v1; v2 ]

and vof_for_or_if_comp = function
  | CompFor (v1, v2, v3, v4) ->
      let v1 = vof_tok v1 in
      let v2 = vof_pattern v2 in
      let v3 = vof_tok v3 in
      let v4 = vof_expr v4 in
      OCaml.VSum ("CompFor", [ v1; v2; v3; v4 ])
  | CompIf (v1, v2) ->
      let v1 = vof_tok v1 in
      let v2 = vof_expr v2 in
      OCaml.VSum ("CompIf", [ v1; v2 ])

and vof_special_ident = function
  | This -> OCaml.VSum ("This", [])
  | Super -> OCaml.VSum ("Super", [])
  | Self -> OCaml.VSum ("Self", [])
  | Cls -> OCaml.VSum ("Cls", [])
  | Parent -> OCaml.VSum ("Parent", [])

and vof_special = function
  | ForOf -> OCaml.VSum ("ForOf", [])
  | Defined -> OCaml.VSum ("Defined", [])
  | Eval -> OCaml.VSum ("Eval", [])
  | Typeof -> OCaml.VSum ("Typeof", [])
  | Instanceof -> OCaml.VSum ("Instanceof", [])
  | Sizeof -> OCaml.VSum ("Sizeof", [])
  | ConcatString v1 ->
      let v1 = vof_interpolated_kind v1 in
      OCaml.VSum ("ConcatString", [ v1 ])
  | Spread -> OCaml.VSum ("Spread", [])
  | InterpolatedElement -> OCaml.VSum ("InterpolatedElement", [])
  | HashSplat -> OCaml.VSum ("HashSplat", [])
  | EncodedString v1 ->
      let v1 = OCaml.vof_string v1 in
      OCaml.VSum ("EncodedString", [ v1 ])
  | Op v1 ->
      let v1 = vof_arithmetic_operator v1 in
      OCaml.VSum ("Op", [ v1 ])
  | IncrDecr v ->
      let v = vof_inc_dec v in
      OCaml.VSum ("IncrDecr", [ v ])
  | NextArrayIndex -> OCaml.VSum ("NextArrayIndex", [])
  | Require -> OCaml.VSum ("Require", [])

and vof_interpolated_kind = function
  | FString v1 ->
      let v1 = OCaml.vof_string v1 in
      OCaml.VSum ("FString", [ v1 ])
  | InterpolatedConcat -> OCaml.VSum ("InterpolatedConcat", [])
  | SequenceConcat -> OCaml.VSum ("SequenceConcat", [])
  | TaggedTemplateLiteral -> OCaml.VSum ("TaggedTemplateLiteral", [])

and vof_inc_dec (v1, v2) =
  let v1 = vof_incr_decr v1 and v2 = vof_prepost v2 in
  OCaml.VTuple [ v1; v2 ]

and vof_incr_decr = function
  | Incr -> OCaml.VSum ("Incr", [])
  | Decr -> OCaml.VSum ("Decr", [])

and vof_prepost = function
  | Prefix -> OCaml.VSum ("Prefix", [])
  | Postfix -> OCaml.VSum ("Postfix", [])

and vof_arithmetic_operator = function
  | NotIs -> OCaml.VSum ("NotIs", [])
  | Is -> OCaml.VSum ("Is", [])
  | NotIn -> OCaml.VSum ("NotIn", [])
  | In -> OCaml.VSum ("In", [])
  | Elvis -> OCaml.VSum ("Elvis", [])
  | NotNullPostfix -> OCaml.VSum ("NotNullPostfix", [])
  | Nullish -> OCaml.VSum ("Nullish", [])
  | Range -> OCaml.VSum ("Range", [])
  | RangeInclusive -> OCaml.VSum ("RangeInclusive", [])
  | RegexpMatch -> OCaml.VSum ("RegexpMatch", [])
  | NotMatch -> OCaml.VSum ("NotMatch", [])
  | Concat -> OCaml.VSum ("Concat", [])
  | Append -> OCaml.VSum ("Append", [])
  | Plus -> OCaml.VSum ("Plus", [])
  | Minus -> OCaml.VSum ("Minus", [])
  | Mult -> OCaml.VSum ("Mult", [])
  | Div -> OCaml.VSum ("Div", [])
  | Mod -> OCaml.VSum ("Mod", [])
  | Pow -> OCaml.VSum ("Pow", [])
  | FloorDiv -> OCaml.VSum ("FloorDiv", [])
  | MatMult -> OCaml.VSum ("MatMult", [])
  | LSL -> OCaml.VSum ("LSL", [])
  | LSR -> OCaml.VSum ("LSR", [])
  | ASR -> OCaml.VSum ("ASR", [])
  | BitOr -> OCaml.VSum ("BitOr", [])
  | BitXor -> OCaml.VSum ("BitXor", [])
  | BitAnd -> OCaml.VSum ("BitAnd", [])
  | BitNot -> OCaml.VSum ("BitNot", [])
  | BitClear -> OCaml.VSum ("BitClear", [])
  | And -> OCaml.VSum ("And", [])
  | Or -> OCaml.VSum ("Or", [])
  | Not -> OCaml.VSum ("Not", [])
  | Xor -> OCaml.VSum ("Xor", [])
  | Pipe -> OCaml.VSum ("Pipe", [])
  | Eq -> OCaml.VSum ("Eq", [])
  | NotEq -> OCaml.VSum ("NotEq", [])
  | PhysEq -> OCaml.VSum ("PhysEq", [])
  | NotPhysEq -> OCaml.VSum ("NotPhysEq", [])
  | Lt -> OCaml.VSum ("Lt", [])
  | LtE -> OCaml.VSum ("LtE", [])
  | Gt -> OCaml.VSum ("Gt", [])
  | GtE -> OCaml.VSum ("GtE", [])
  | Cmp -> OCaml.VSum ("Cmp", [])
  | Length -> OCaml.VSum ("Length", [])
  | Background -> OCaml.VSum ("Background", [])
  | LDA -> OCaml.VSum ("LDA", [])
  | RDA -> OCaml.VSum ("RDA", [])
  | LSA -> OCaml.VSum ("LSA", [])
  | RSA -> OCaml.VSum ("RSA", [])

and vof_arguments v = vof_bracket (OCaml.vof_list vof_argument) v

and vof_argument = function
  | Arg v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("Arg", [ v1 ])
  | ArgKwd (v1, v2) ->
      let v1 = vof_ident v1 and v2 = vof_expr v2 in
      OCaml.VSum ("ArgKwd", [ v1; v2 ])
  | ArgKwdOptional (v1, v2) ->
      let v1 = vof_ident v1 and v2 = vof_expr v2 in
      OCaml.VSum ("ArgKwdOptional", [ v1; v2 ])
  | ArgType v1 ->
      let v1 = vof_type_ v1 in
      OCaml.VSum ("ArgType", [ v1 ])
  | OtherArg (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherArg", [ v1; v2 ])

and vof_type_ { t; t_attrs } =
  let bnds = [] in
  let arg = vof_type_kind t in
  let bnd = ("t", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_attribute t_attrs in
  let bnd = ("t_attrs", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_type_kind = function
  | TyEllipsis v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("TyEllipsis", [ v1 ])
  | TyRecordAnon (v0, v1) ->
      let v0 = vof_class_kind v0 in
      let v1 = vof_bracket (OCaml.vof_list vof_field) v1 in
      OCaml.VSum ("TyRecordAnon", [ v0; v1 ])
  | TyOr (v1, v2, v3) ->
      let v1 = vof_type_ v1 in
      let v2 = vof_tok v2 in
      let v3 = vof_type_ v3 in
      OCaml.VSum ("TyOr", [ v1; v2; v3 ])
  | TyAnd (v1, v2, v3) ->
      let v1 = vof_type_ v1 in
      let v2 = vof_tok v2 in
      let v3 = vof_type_ v3 in
      OCaml.VSum ("TyAnd", [ v1; v2; v3 ])
  | TyFun (v1, v2) ->
      let v1 = OCaml.vof_list vof_parameter v1 and v2 = vof_type_ v2 in
      OCaml.VSum ("TyFun", [ v1; v2 ])
  | TyApply (v1, v2) ->
      let v1 = vof_type_ v1 and v2 = vof_type_arguments v2 in
      OCaml.VSum ("TyApply", [ v1; v2 ])
  | TyN v1 ->
      let v1 = vof_name v1 in
      OCaml.VSum ("TyN", [ v1 ])
  | TyVar v1 ->
      let v1 = vof_ident v1 in
      OCaml.VSum ("TyVar", [ v1 ])
  | TyAny v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("TyAny", [ v1 ])
  | TyArray (v1, v2) ->
      let v1 = vof_bracket (OCaml.vof_option vof_expr) v1
      and v2 = vof_type_ v2 in
      OCaml.VSum ("TyArray", [ v1; v2 ])
  | TyPointer (t, v1) ->
      let t = vof_tok t in
      let v1 = vof_type_ v1 in
      OCaml.VSum ("TyPointer", [ t; v1 ])
  | TyRef (t, v1) ->
      let t = vof_tok t in
      let v1 = vof_type_ v1 in
      OCaml.VSum ("TyRef", [ t; v1 ])
  | TyTuple v1 ->
      let v1 = vof_bracket (OCaml.vof_list vof_type_) v1 in
      OCaml.VSum ("TyTuple", [ v1 ])
  | TyQuestion (v1, t) ->
      let v1 = vof_type_ v1 in
      let t = vof_tok t in
      OCaml.VSum ("TyQuestion", [ t; v1 ])
  | TyRest (t, v1) ->
      let t = vof_tok t in
      let v1 = vof_type_ v1 in
      OCaml.VSum ("TyRest", [ v1; t ])
  | TyExpr v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("TyExpr", [ v1 ])
  | OtherType (v1, v2) ->
      let v1 = vof_todo_kind v1 in
      let v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherType", [ v1; v2 ])

and vof_type_arguments v = vof_bracket (OCaml.vof_list vof_type_argument) v

and vof_type_argument = function
  | TA v1 ->
      let v1 = vof_type_ v1 in
      OCaml.VSum ("TA", [ v1 ])
  | TAWildcard (v1, v2) ->
      let v1 = vof_tok v1 in
      let v2 =
        OCaml.vof_option
          (fun (v1, v2) ->
            let v1 = vof_wrap OCaml.vof_bool v1 in
            let v2 = vof_type_ v2 in
            OCaml.VTuple [ v1; v2 ])
          v2
      in
      OCaml.VSum ("AWildcard", [ v1; v2 ])
  | TAExpr v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("TAExpr", [ v1 ])
  | OtherTypeArg (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherTypeArg", [ v1; v2 ])

and vof_keyword_attribute = function
  | SealedClass -> OCaml.VSum ("SealedClass", [])
  | AnnotationClass -> OCaml.VSum ("AnnotationClass", [])
  | RecordClass -> OCaml.VSum ("RecordClass", [])
  | EnumClass -> OCaml.VSum ("EnumClass", [])
  | Lazy -> OCaml.VSum ("Lazy", [])
  | Static -> OCaml.VSum ("Static", [])
  | Volatile -> OCaml.VSum ("Volatile", [])
  | Extern -> OCaml.VSum ("Extern", [])
  | Public -> OCaml.VSum ("Public", [])
  | Private -> OCaml.VSum ("Private", [])
  | Protected -> OCaml.VSum ("Protected", [])
  | Abstract -> OCaml.VSum ("Abstract", [])
  | Final -> OCaml.VSum ("Final", [])
  | Override -> OCaml.VSum ("Override", [])
  | Var -> OCaml.VSum ("Var", [])
  | Let -> OCaml.VSum ("Let", [])
  | Const -> OCaml.VSum ("Const", [])
  | Mutable -> OCaml.VSum ("Mutable", [])
  | Generator -> OCaml.VSum ("Generator", [])
  | Async -> OCaml.VSum ("Async", [])
  | Recursive -> OCaml.VSum ("Recursive", [])
  | MutuallyRecursive -> OCaml.VSum ("MutuallyRecursive", [])
  | Inline -> OCaml.VSum ("Inline", [])
  | Ctor -> OCaml.VSum ("Ctor", [])
  | Dtor -> OCaml.VSum ("Dtor", [])
  | Getter -> OCaml.VSum ("Getter", [])
  | Setter -> OCaml.VSum ("Setter", [])
  | Optional -> OCaml.VSum ("Optional", [])
  | NotNull -> OCaml.VSum ("NotNull", [])
  | Unsafe -> OCaml.VSum ("Unsafe", [])
  | DefaultImpl -> OCaml.VSum ("DefaultImpl", [])
  | Throws -> OCaml.VSum ("Throws", [])
  | Rethrows -> OCaml.VSum ("Rethrows", [])

and vof_attribute = function
  | KeywordAttr x ->
      let v1 = vof_wrap vof_keyword_attribute x in
      OCaml.VSum ("KeywordAttr", [ v1 ])
  | NamedAttr (t, v1, v3) ->
      let t = vof_tok t in
      let v1 = vof_name v1
      and v3 = vof_bracket (OCaml.vof_list vof_argument) v3 in
      OCaml.VSum ("NamedAttr", [ t; v1; v3 ])
  | OtherAttribute (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherAttribute", [ v1; v2 ])

and vof_stmt st =
  (* todo: dump also the s_id? *)
  match st.s with
  | DisjStmt (v1, v2) ->
      let v1 = vof_stmt v1 in
      let v2 = vof_stmt v2 in
      OCaml.VSum ("DisjStmt", [ v1; v2 ])
  | ExprStmt (v1, t) ->
      let v1 = vof_expr v1 in
      let t = vof_tok t in
      OCaml.VSum ("ExprStmt", [ v1; t ])
  | DefStmt v1 ->
      let v1 = vof_definition v1 in
      OCaml.VSum ("DefStmt", [ v1 ])
  | DirectiveStmt v1 ->
      let v1 = vof_directive v1 in
      OCaml.VSum ("DirectiveStmt", [ v1 ])
  | Block v1 ->
      let v1 = vof_bracket (OCaml.vof_list vof_stmt) v1 in
      OCaml.VSum ("Block", [ v1 ])
  | If (t, v1, v2, v3) ->
      let t = vof_tok t in
      let v1 = vof_condition v1
      and v2 = vof_stmt v2
      and v3 = OCaml.vof_option vof_stmt v3 in
      OCaml.VSum ("If", [ t; v1; v2; v3 ])
  | While (t, v1, v2) ->
      let t = vof_tok t in
      let v1 = vof_condition v1 and v2 = vof_stmt v2 in
      OCaml.VSum ("While", [ t; v1; v2 ])
  | DoWhile (t, v1, v2) ->
      let t = vof_tok t in
      let v1 = vof_stmt v1 and v2 = vof_expr v2 in
      OCaml.VSum ("DoWhile", [ t; v1; v2 ])
  | For (t, v1, v2) ->
      let t = vof_tok t in
      let v1 = vof_for_header v1 and v2 = vof_stmt v2 in
      OCaml.VSum ("For", [ t; v1; v2 ])
  | Switch (v0, v1, v2) ->
      let v0 = vof_tok v0 in
      let v1 = OCaml.vof_option vof_condition v1
      and v2 = OCaml.vof_list vof_case_and_body v2 in
      OCaml.VSum ("Switch", [ v0; v1; v2 ])
  | Return (t, v1, sc) ->
      let t = vof_tok t in
      let v1 = OCaml.vof_option vof_expr v1 in
      let sc = vof_tok sc in
      OCaml.VSum ("Return", [ t; v1; sc ])
  | Continue (t, v1, sc) ->
      let t = vof_tok t in
      let v1 = vof_label_ident v1 in
      let sc = vof_tok sc in
      OCaml.VSum ("Continue", [ t; v1; sc ])
  | Break (t, v1, sc) ->
      let t = vof_tok t in
      let v1 = vof_label_ident v1 in
      let sc = vof_tok sc in
      OCaml.VSum ("Break", [ t; v1; sc ])
  | Label (v1, v2) ->
      let v1 = vof_label v1 and v2 = vof_stmt v2 in
      OCaml.VSum ("Label", [ v1; v2 ])
  | Goto (t, v1, sc) ->
      let t = vof_tok t in
      let v1 = vof_label v1 in
      let sc = vof_tok sc in
      OCaml.VSum ("Goto", [ t; v1; sc ])
  | Throw (t, v1, sc) ->
      let t = vof_tok t in
      let v1 = vof_expr v1 in
      let sc = vof_tok sc in
      OCaml.VSum ("Throw", [ t; v1; sc ])
  | Try (t, v1, v2, v3, v4) ->
      let t = vof_tok t in
      let v1 = vof_stmt v1
      and v2 = OCaml.vof_list vof_catch v2
      and v3 = OCaml.vof_option vof_try_else v3
      and v4 = OCaml.vof_option vof_finally v4 in
      OCaml.VSum ("Try", [ t; v1; v2; v3; v4 ])
  | WithUsingResource (t, v1, v2) ->
      let t = vof_tok t in
      let v1 = OCaml.vof_list vof_stmt v1 in
      let v2 = vof_stmt v2 in
      OCaml.VSum ("WithUsingResource", [ t; v1; v2 ])
  | Assert (t, args, sc) ->
      let t = vof_tok t in
      let args = vof_arguments args in
      let sc = vof_tok sc in
      OCaml.VSum ("Assert", [ t; args; sc ])
  | OtherStmtWithStmt (v1, v2, v3) ->
      let v1 = vof_other_stmt_with_stmt_operator v1
      and v2 = OCaml.vof_list vof_any v2
      and v3 = vof_stmt v3 in
      OCaml.VSum ("OtherStmtWithStmt", [ v1; v2; v3 ])
  | OtherStmt (v1, v2) ->
      let v1 = vof_other_stmt_operator v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherStmt", [ v1; v2 ])
  | RawStmt x ->
      let x = vof_raw_tree x in
      OCaml.VSum ("RawStmt", [ x ])

and vof_condition = function
  | Cond v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("Cond", [ v1 ])
  | OtherCond (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherCond", [ v1; v2 ])

and vof_other_stmt_with_stmt_operator = function
  | OSWS_Block v1 ->
      let v1 = vof_todo_kind v1 in
      OCaml.VSum ("OSWS_Block", [ v1 ])
  | OSWS_With -> OCaml.VSum ("OSWS_With", [])
  | OSWS_Else_in_try -> OCaml.VSum ("OSWS_Else_in_try", [])
  | OSWS_Iterator -> OCaml.VSum ("OSWS_Iterator", [])
  | OSWS_SEH -> OCaml.VSum ("OSWS_SEH", [])
  | OSWS_Todo -> OCaml.VSum ("OSWS_Todo", [])

and vof_label_ident = function
  | LNone -> OCaml.VSum ("LNone", [])
  | LId v1 ->
      let v1 = vof_label v1 in
      OCaml.VSum ("LId", [ v1 ])
  | LInt v1 ->
      let v1 = vof_wrap OCaml.vof_int v1 in
      OCaml.VSum ("LInt", [ v1 ])
  | LDynamic v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("LDynamic", [ v1 ])

and vof_case_and_body = function
  | CasesAndBody (v1, v2) ->
      let v1 = OCaml.vof_list vof_case v1 and v2 = vof_stmt v2 in
      OCaml.VSum ("CasesAndBody", [ v1; v2 ])
  | CaseEllipsis v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("CaseEllipsis", [ v1 ])

and vof_case = function
  | OtherCase (v1, v2) ->
      let v1 = vof_todo_kind v1 in
      let v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherCase", [ v1; v2 ])
  | Case (t, v1) ->
      let t = vof_tok t in
      let v1 = vof_pattern v1 in
      OCaml.VSum ("Case", [ t; v1 ])
  | CaseEqualExpr (v1, v2) ->
      let v1 = vof_tok v1 in
      let v2 = vof_expr v2 in
      OCaml.VSum ("CaseEqualExpr", [ v1; v2 ])
  | Default t ->
      let t = vof_tok t in
      OCaml.VSum ("Default", [ t ])

and vof_catch (t, v1, v2) =
  let t = vof_tok t in
  let v1 = vof_catch_exn v1 and v2 = vof_stmt v2 in
  OCaml.VTuple [ t; v1; v2 ]

and vof_catch_exn = function
  | OtherCatch (v1, v2) ->
      let v1 = vof_todo_kind v1 in
      let v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherCatch", [ v1; v2 ])
  | CatchPattern v ->
      let v = vof_pattern v in
      OCaml.VSum ("CatchPattern", [ v ])
  | CatchParam v1 ->
      let v1 = vof_parameter_classic v1 in
      OCaml.VSum ("CatchParam", [ v1 ])

and vof_try_else v = vof_tok_and_stmt v
and vof_finally v = vof_tok_and_stmt v

and vof_tok_and_stmt (t, v) =
  let t = vof_tok t in
  let v = vof_stmt v in
  OCaml.VTuple [ t; v ]

and vof_label v = vof_ident v

and vof_for_header = function
  | ForClassic (v1, v2, v3) ->
      let v1 = OCaml.vof_list vof_for_var_or_expr v1
      and v2 = OCaml.vof_option vof_expr v2
      and v3 = OCaml.vof_option vof_expr v3 in
      OCaml.VSum ("ForClassic", [ v1; v2; v3 ])
  | ForEach v1 ->
      let v1 = vof_for_each v1 in
      OCaml.VSum ("ForEach", [ v1 ])
  | MultiForEach v1 ->
      let v1 = OCaml.vof_list vof_multi_for_each v1 in
      OCaml.VSum ("MultiForEach", [ v1 ])
  | ForEllipsis t ->
      let t = vof_tok t in
      OCaml.VSum ("ForEllipsis", [ t ])

and vof_for_each (v1, t, v2) =
  let t = vof_tok t in
  let v1 = vof_pattern v1 and v2 = vof_expr v2 in
  OCaml.VTuple [ v1; t; v2 ]

and vof_multi_for_each = function
  | FE v1 ->
      let v1 = vof_for_each v1 in
      OCaml.VSum ("FE", [ v1 ])
  | FECond (v1, t, v2) ->
      let t = vof_tok t in
      let v1 = vof_for_each v1 and v2 = vof_expr v2 in
      OCaml.VSum ("FECond", [ v1; t; v2 ])
  | FEllipsis t ->
      let t = vof_tok t in
      OCaml.VSum ("FEllipsis", [ t ])

and vof_for_var_or_expr = function
  | ForInitVar (v1, v2) ->
      let v1 = vof_entity v1 and v2 = vof_variable_definition v2 in
      OCaml.VSum ("ForInitVar", [ v1; v2 ])
  | ForInitExpr v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("ForInitExpr", [ v1 ])

and vof_other_stmt_operator = function
  | OS_ExprStmt2 -> OCaml.VSum ("OS_ExprStmt2", [])
  | OS_Redo -> OCaml.VSum ("OS_Redo", [])
  | OS_Retry -> OCaml.VSum ("OS_Retry", [])
  | OS_Todo -> OCaml.VSum ("OS_Todo", [])
  | OS_Delete -> OCaml.VSum ("OS_Delete", [])
  | OS_Async -> OCaml.VSum ("OS_Async", [])
  | OS_ForOrElse -> OCaml.VSum ("OS_ForOrElse", [])
  | OS_WhileOrElse -> OCaml.VSum ("OS_WhileOrElse", [])
  | OS_TryOrElse -> OCaml.VSum ("OS_TryOrElse", [])
  | OS_ThrowFrom -> OCaml.VSum ("OS_ThrowFrom", [])
  | OS_ThrowNothing -> OCaml.VSum ("OS_ThrowNothing", [])
  | OS_ThrowArgsLocation -> OCaml.VSum ("OS_ThrowArgsLocation", [])
  | OS_GlobalComplex -> OCaml.VSum ("OS_GlobalComplex", [])
  | OS_Pass -> OCaml.VSum ("OS_Pass", [])
  | OS_Asm -> OCaml.VSum ("OS_Asm", [])
  | OS_Go -> OCaml.VSum ("OS_Go", [])
  | OS_Defer -> OCaml.VSum ("OS_Defer", [])
  | OS_Extension -> OCaml.VSum ("OS_Extension", [])
  | OS_Fallthrough -> OCaml.VSum ("OS_Fallthrough", [])

and vof_pattern = function
  | PatEllipsis v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("PatEllipsis", [ v1 ])
  | PatId (v1, v2) ->
      let v1 = vof_ident v1 and v2 = vof_id_info v2 in
      OCaml.VSum ("PatId", [ v1; v2 ])
  | PatLiteral v1 ->
      let v1 = vof_literal v1 in
      OCaml.VSum ("PatLiteral", [ v1 ])
  | PatType v1 ->
      let v1 = vof_type_ v1 in
      OCaml.VSum ("PatType", [ v1 ])
  | PatRecord v1 ->
      let v1 =
        vof_bracket
          (OCaml.vof_list (fun (v1, v2) ->
               let v1 = vof_dotted_ident v1 and v2 = vof_pattern v2 in
               OCaml.VTuple [ v1; v2 ]))
          v1
      in
      OCaml.VSum ("PatRecord", [ v1 ])
  | PatConstructor (v1, v2) ->
      let v1 = vof_name v1 and v2 = OCaml.vof_list vof_pattern v2 in
      OCaml.VSum ("PatConstructor", [ v1; v2 ])
  | PatWhen (v1, v2) ->
      let v1 = vof_pattern v1 and v2 = vof_expr v2 in
      OCaml.VSum ("PatWhen", [ v1; v2 ])
  | PatAs (v1, v2) ->
      let v1 = vof_pattern v1
      and v2 =
        match v2 with
        | v1, v2 ->
            let v1 = vof_ident v1 and v2 = vof_id_info v2 in
            OCaml.VTuple [ v1; v2 ]
      in
      OCaml.VSum ("PatAs", [ v1; v2 ])
  | PatTuple v1 ->
      let v1 = vof_bracket (OCaml.vof_list vof_pattern) v1 in
      OCaml.VSum ("PatTuple", [ v1 ])
  | PatList v1 ->
      let v1 = vof_bracket (OCaml.vof_list vof_pattern) v1 in
      OCaml.VSum ("PatList", [ v1 ])
  | PatKeyVal (v1, v2) ->
      let v1 = vof_pattern v1 and v2 = vof_pattern v2 in
      OCaml.VSum ("PatKeyVal", [ v1; v2 ])
  | PatWildcard v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("PatWildcard", [ v1 ])
  | PatDisj (v1, v2) ->
      let v1 = vof_pattern v1 and v2 = vof_pattern v2 in
      OCaml.VSum ("PatDisj", [ v1; v2 ])
  | PatTyped (v1, v2) ->
      let v1 = vof_pattern v1 and v2 = vof_type_ v2 in
      OCaml.VSum ("PatTyped", [ v1; v2 ])
  | DisjPat (v1, v2) ->
      let v1 = vof_pattern v1 and v2 = vof_pattern v2 in
      OCaml.VSum ("DisjPat", [ v1; v2 ])
  | OtherPat (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherPat", [ v1; v2 ])

and vof_definition (v1, v2) =
  let v1 = vof_entity v1 and v2 = vof_definition_kind v2 in
  OCaml.VTuple [ v1; v2 ]

and vof_entity { name = v_name; attrs = v_attrs; tparams = v_tparams } =
  let bnds = [] in
  let arg =
    OCaml.vof_option (vof_bracket (OCaml.vof_list vof_type_parameter)) v_tparams
  in
  let bnd = ("tparams", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_attribute v_attrs in
  let bnd = ("attrs", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_entity_name v_name in
  let bnd = ("name", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_enum_entry_definition { ee_args; ee_body } =
  let bnds = [] in
  let arg = OCaml.vof_option (vof_bracket (OCaml.vof_list vof_field)) ee_body in
  let bnd = ("ee_body", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_arguments ee_args in
  let bnd = ("ee_args", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_definition_kind = function
  | EnumEntryDef v1 ->
      let v1 = vof_enum_entry_definition v1 in
      OCaml.VSum ("EnumEntryDef", [ v1 ])
  | FuncDef v1 ->
      let v1 = vof_function_definition v1 in
      OCaml.VSum ("FuncDef", [ v1 ])
  | VarDef v1 ->
      let v1 = vof_variable_definition v1 in
      OCaml.VSum ("VarDef", [ v1 ])
  | FieldDefColon v1 ->
      let v1 = vof_variable_definition v1 in
      OCaml.VSum ("FieldDefColon", [ v1 ])
  | ClassDef v1 ->
      let v1 = vof_class_definition v1 in
      OCaml.VSum ("ClassDef", [ v1 ])
  | TypeDef v1 ->
      let v1 = vof_type_definition v1 in
      OCaml.VSum ("TypeDef", [ v1 ])
  | ModuleDef v1 ->
      let v1 = vof_module_definition v1 in
      OCaml.VSum ("ModuleDef", [ v1 ])
  | MacroDef v1 ->
      let v1 = vof_macro_definition v1 in
      OCaml.VSum ("MacroDef", [ v1 ])
  | Signature v1 ->
      let v1 = vof_signature_definition v1 in
      OCaml.VSum ("Signature", [ v1 ])
  | UseOuterDecl v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("UseOuterDecl", [ v1 ])
  | OtherDef (v1, v2) ->
      let v1 = vof_todo_kind v1 in
      let v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherDef", [ v1; v2 ])

and vof_module_definition { mbody = v_mbody } =
  let bnds = [] in
  let arg = vof_module_definition_kind v_mbody in
  let bnd = ("mbody", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_module_definition_kind = function
  | ModuleAlias v1 ->
      let v1 = vof_dotted_ident v1 in
      OCaml.VSum ("ModuleAlias", [ v1 ])
  | ModuleStruct (v1, v2) ->
      let v1 = OCaml.vof_option vof_dotted_name v1
      and v2 = OCaml.vof_list vof_item v2 in
      OCaml.VSum ("ModuleStruct", [ v1; v2 ])
  | OtherModule (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherModule", [ v1; v2 ])

and vof_macro_definition
    { macroparams = v_macroparams; macrobody = v_macrobody } =
  let bnds = [] in
  let arg = OCaml.vof_list vof_any v_macrobody in
  let bnd = ("macrobody", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_ident v_macroparams in
  let bnd = ("macroparams", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_signature_definition { sig_tok; sig_type } =
  let bnds = [] in
  let arg = vof_type_ sig_type in
  let bnd = ("sig_type", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_tok sig_tok in
  let bnd = ("sig_tok", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_type_parameter = function
  | TParamEllipsis v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("TParamEllipsis", [ v1 ])
  | TP v1 ->
      let v1 = vof_type_parameter_classic v1 in
      OCaml.VSum ("TP", [ v1 ])
  | OtherTypeParam (t, xs) ->
      let t = vof_todo_kind t and xs = OCaml.vof_list vof_any xs in
      OCaml.VSum ("OtherTypeParam", [ t; xs ])

and vof_type_parameter_classic
    {
      tp_id = v1;
      tp_attrs = v2;
      tp_bounds = v3;
      tp_default = v4;
      tp_variance = v5;
    } =
  let bnds = [] in
  let arg = OCaml.vof_option (vof_wrap vof_variance) v5 in
  let bnd = ("tp_variance", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_type_ v4 in
  let bnd = ("tp_default", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_type_ v3 in
  let bnd = ("tp_bounds", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_attribute v2 in
  let bnd = ("tp_attrs", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_ident v1 in
  let bnd = ("tp_id", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_variance = function
  | Covariant -> OCaml.VSum ("Covariant", [])
  | Contravariant -> OCaml.VSum ("Contravariant", [])

and vof_function_kind = function
  | Function -> OCaml.VSum ("Function", [])
  | LambdaKind -> OCaml.VSum ("LambdaKind", [])
  | Method -> OCaml.VSum ("Method", [])
  | Arrow -> OCaml.VSum ("Arrow", [])
  | BlockCases -> OCaml.VSum ("BlockCases", [])

and vof_function_definition
    { fkind; fparams = v_fparams; frettype = v_frettype; fbody = v_fbody } =
  let bnds = [] in
  let arg = vof_function_body v_fbody in
  let bnd = ("fbody", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_type_ v_frettype in
  let bnd = ("frettype", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_parameters v_fparams in
  let bnd = ("fparams", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_wrap vof_function_kind fkind in
  let bnd = ("fkind", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_parameters v = vof_bracket (OCaml.vof_list vof_parameter) v

and vof_parameter = function
  | Param v1 ->
      let v1 = vof_parameter_classic v1 in
      OCaml.VSum ("Param", [ v1 ])
  | ParamRest (v0, v1) ->
      let v0 = vof_tok v0 in
      let v1 = vof_parameter_classic v1 in
      OCaml.VSum ("ParamRest", [ v0; v1 ])
  | ParamHashSplat (v0, v1) ->
      let v0 = vof_tok v0 in
      let v1 = vof_parameter_classic v1 in
      OCaml.VSum ("ParamHashSplat", [ v0; v1 ])
  | ParamPattern v1 ->
      let v1 = vof_pattern v1 in
      OCaml.VSum ("ParamPattern", [ v1 ])
  | ParamEllipsis v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("ParamEllipsis", [ v1 ])
  | ParamReceiver v1 ->
      let v1 = vof_parameter_classic v1 in
      OCaml.VSum ("ParamReceiver", [ v1 ])
  | OtherParam (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherParam", [ v1; v2 ])

and vof_parameter_classic
    {
      pname = v_pname;
      pdefault = v_pdefault;
      ptype = v_ptype;
      pattrs = v_pattrs;
      pinfo = v_pinfo;
    } =
  let bnds = [] in
  let arg = vof_id_info v_pinfo in
  let bnd = ("pinfo", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_attribute v_pattrs in
  let bnd = ("pattrs", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_type_ v_ptype in
  let bnd = ("ptype", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_expr v_pdefault in
  let bnd = ("pdefault", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_ident v_pname in
  let bnd = ("pname", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_function_body = function
  | FBStmt v1 ->
      let v1 = vof_stmt v1 in
      OCaml.VSum ("FBStmt", [ v1 ])
  | FBExpr v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("FBExpr", [ v1 ])
  | FBDecl v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("FBDecl", [ v1 ])
  | FBNothing -> OCaml.VSum ("FBNothing", [])

and vof_variable_definition { vinit = v_vinit; vtype = v_vtype; vtok } =
  let bnds = [] in
  let arg = OCaml.vof_option vof_tok vtok in
  let bnd = ("vtok", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_type_ v_vtype in
  let bnd = ("vtype", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_option vof_expr v_vinit in
  let bnd = ("vinit", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_field = function
  | F v1 ->
      let v1 = vof_stmt v1 in
      OCaml.VSum ("F", [ v1 ])

and vof_type_definition { tbody = v_tbody } =
  let bnds = [] in
  let arg = vof_type_definition_kind v_tbody in
  let bnd = ("tbody", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_type_definition_kind = function
  | OrType v1 ->
      let v1 = OCaml.vof_list vof_or_type_element v1 in
      OCaml.VSum ("OrType", [ v1 ])
  | AndType v1 ->
      let v1 = vof_bracket (OCaml.vof_list vof_field) v1 in
      OCaml.VSum ("AndType", [ v1 ])
  | AliasType v1 ->
      let v1 = vof_type_ v1 in
      OCaml.VSum ("AliasType", [ v1 ])
  | NewType v1 ->
      let v1 = vof_type_ v1 in
      OCaml.VSum ("NewType", [ v1 ])
  | Exception (v1, v2) ->
      let v1 = vof_ident v1 and v2 = OCaml.vof_list vof_type_ v2 in
      OCaml.VSum ("Exception", [ v1; v2 ])
  | AbstractType v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("AbstractType", [ v1 ])
  | OtherTypeKind (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherTypeKind", [ v1; v2 ])

and vof_or_type_element = function
  | OrConstructor (v1, v2) ->
      let v1 = vof_ident v1 and v2 = OCaml.vof_list vof_type_ v2 in
      OCaml.VSum ("OrConstructor", [ v1; v2 ])
  | OrEnum (v1, v2) ->
      let v1 = vof_ident v1 and v2 = OCaml.vof_option vof_expr v2 in
      OCaml.VSum ("OrEnum", [ v1; v2 ])
  | OrUnion (v1, v2) ->
      let v1 = vof_ident v1 and v2 = vof_type_ v2 in
      OCaml.VSum ("OrUnion", [ v1; v2 ])
  | OrEllipsis v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("OrEllipsis", [ v1 ])

and vof_class_definition
    {
      ckind = v_ckind;
      cextends = v_cextends;
      cimplements = v_cimplements;
      cbody = v_cbody;
      cmixins = v_cmixins;
      cparams;
    } =
  let bnds = [] in
  let arg = vof_bracket (OCaml.vof_list vof_field) v_cbody in
  let bnd = ("cbody", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_parameters cparams in
  let bnd = ("cparams", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_type_ v_cmixins in
  let bnd = ("cmixins", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_type_ v_cimplements in
  let bnd = ("cimplements", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_class_parent v_cextends in
  let bnd = ("cextends", arg) in
  let bnds = bnd :: bnds in
  let arg = vof_class_kind v_ckind in
  let bnd = ("ckind", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_class_parent (v1, v2) =
  let v1 = vof_type_ v1 in
  let v2 = OCaml.vof_option vof_arguments v2 in
  OCaml.VTuple [ v1; v2 ]

and vof_class_kind x = vof_wrap vof_class_kind_bis x

and vof_class_kind_bis = function
  | Class -> OCaml.VSum ("Class", [])
  | Interface -> OCaml.VSum ("Interface", [])
  | Trait -> OCaml.VSum ("Trait", [])
  | Object -> OCaml.VSum ("Object", [])

and vof_ident_and_id_info (v1, v2) =
  let v1 = vof_ident v1 in
  let v2 = vof_id_info v2 in
  OCaml.VTuple [ v1; v2 ]

and vof_directive { d; d_attrs } =
  let bnds = [] in
  let arg = vof_directive_kind d in
  let bnd = ("d", arg) in
  let bnds = bnd :: bnds in
  let arg = OCaml.vof_list vof_attribute d_attrs in
  let bnd = ("d_attrs", arg) in
  let bnds = bnd :: bnds in
  OCaml.VDict bnds

and vof_directive_kind = function
  | ImportFrom (t, v1, v2) ->
      let t = vof_tok t in
      let v1 = vof_module_name v1 in
      let v2 = OCaml.vof_list vof_import_from_kind v2 in
      OCaml.VSum ("ImportFrom", [ t; v1; v2 ])
  | ImportAs (t, v1, v2) ->
      let t = vof_tok t in
      let v1 = vof_module_name v1
      and v2 = OCaml.vof_option vof_ident_and_id_info v2 in
      OCaml.VSum ("ImportAs", [ t; v1; v2 ])
  | ImportAll (t, v1, v2) ->
      let t = vof_tok t in
      let v1 = vof_module_name v1 and v2 = vof_tok v2 in
      OCaml.VSum ("ImportAll", [ t; v1; v2 ])
  | Package (t, v1) ->
      let t = vof_tok t in
      let v1 = vof_dotted_ident v1 in
      OCaml.VSum ("Package", [ t; v1 ])
  | PackageEnd t ->
      let t = vof_tok t in
      OCaml.VSum ("PackageEnd", [ t ])
  | Pragma (v1, v2) ->
      let v1 = vof_ident v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("Pragma", [ v1; v2 ])
  | OtherDirective (v1, v2) ->
      let v1 = vof_todo_kind v1 and v2 = OCaml.vof_list vof_any v2 in
      OCaml.VSum ("OtherDirective", [ v1; v2 ])

and vof_alias x = vof_ident_and_id_info x

and vof_import_from_kind = function
  | Direct v1 ->
      let v1 = vof_alias v1 in
      OCaml.VSum ("Direct", [ v1 ])
  | Aliased (v1, v2) ->
      let v1 = vof_ident v1 and v2 = vof_alias v2 in
      OCaml.VSum ("Aliased", [ v1; v2 ])

and vof_item x = vof_stmt x
and vof_program v = OCaml.vof_list vof_item v

and vof_partial = function
  | PartialMatch (v1, v2) ->
      let v1 = vof_tok v1 in
      let v2 = vof_expr v2 in
      OCaml.VSum ("PartialMatch", [ v1; v2 ])
  | PartialLambdaOrFuncDef v1 ->
      let v1 = vof_function_definition v1 in
      OCaml.VSum ("PartialLambdaOrFuncDef", [ v1 ])
  | PartialDef v1 ->
      let v1 = vof_definition v1 in
      OCaml.VSum ("PartialDef", [ v1 ])
  | PartialIf (v1, v2) ->
      let v1 = vof_tok v1 in
      let v2 = vof_expr v2 in
      OCaml.VSum ("PartialIf", [ v1; v2 ])
  | PartialTry (v1, v2) ->
      let v1 = vof_tok v1 in
      let v2 = vof_stmt v2 in
      OCaml.VSum ("PartialTry", [ v1; v2 ])
  | PartialFinally (v1, v2) ->
      let v1 = vof_tok v1 in
      let v2 = vof_stmt v2 in
      OCaml.VSum ("PartialFinally", [ v1; v2 ])
  | PartialCatch v1 ->
      let v1 = vof_catch v1 in
      OCaml.VSum ("PartialCatch", [ v1 ])
  | PartialSingleField (v1, v2, v3) ->
      let v1 = vof_wrap OCaml.vof_string v1 in
      let v2 = vof_tok v2 in
      let v3 = vof_expr v3 in
      OCaml.VSum ("PartialSingleField", [ v1; v2; v3 ])
  | PartialSwitchCase v1 ->
      let v1 = vof_case_and_body v1 in
      OCaml.VSum ("PartialSwitchCase", [ v1 ])

and vof_any = function
  | Raw v1 ->
      let v1 = vof_raw_tree v1 in
      OCaml.VSum ("Raw", [ v1 ])
  | Name v1 ->
      let v1 = vof_name v1 in
      OCaml.VSum ("Name", [ v1 ])
  | Xmls v1 ->
      let v1 = OCaml.vof_list vof_xml_body v1 in
      OCaml.VSum ("Xmls", [ v1 ])
  | ForOrIfComp v1 ->
      let v1 = vof_for_or_if_comp v1 in
      OCaml.VSum ("ForOrIfComp", [ v1 ])
  | Tp v1 ->
      let v1 = vof_type_parameter v1 in
      OCaml.VSum ("Tp", [ v1 ])
  | Ta v1 ->
      let v1 = vof_type_argument v1 in
      OCaml.VSum ("Ta", [ v1 ])
  | Cs v1 ->
      let v1 = vof_case v1 in
      OCaml.VSum ("Cs", [ v1 ])
  | Str v1 ->
      let v1 = vof_bracket (vof_wrap OCaml.vof_string) v1 in
      OCaml.VSum ("Str", [ v1 ])
  | Args v1 ->
      let v1 = OCaml.vof_list vof_argument v1 in
      OCaml.VSum ("Args", [ v1 ])
  | Params v1 ->
      let v1 = OCaml.vof_list vof_parameter v1 in
      OCaml.VSum ("Params", [ v1 ])
  | Flds v1 ->
      let v1 = OCaml.vof_list vof_field v1 in
      OCaml.VSum ("Flds", [ v1 ])
  | Anys v1 ->
      let v1 = OCaml.vof_list vof_any v1 in
      OCaml.VSum ("Anys", [ v1 ])
  | Partial v1 ->
      let v1 = vof_partial v1 in
      OCaml.VSum ("Partial", [ v1 ])
  | TodoK v1 ->
      let v1 = vof_ident v1 in
      OCaml.VSum ("TodoK", [ v1 ])
  | Tk v1 ->
      let v1 = vof_tok v1 in
      OCaml.VSum ("Tk", [ v1 ])
  | Modn v1 ->
      let v1 = vof_module_name v1 in
      OCaml.VSum ("Modn", [ v1 ])
  | ModDk v1 ->
      let v1 = vof_module_definition_kind v1 in
      OCaml.VSum ("ModDk", [ v1 ])
  | En v1 ->
      let v1 = vof_entity v1 in
      OCaml.VSum ("En", [ v1 ])
  | E v1 ->
      let v1 = vof_expr v1 in
      OCaml.VSum ("E", [ v1 ])
  | S v1 ->
      let v1 = vof_stmt v1 in
      OCaml.VSum ("S", [ v1 ])
  | Ss v1 ->
      let v1 = OCaml.vof_list vof_stmt v1 in
      OCaml.VSum ("Ss", [ v1 ])
  | T v1 ->
      let v1 = vof_type_ v1 in
      OCaml.VSum ("T", [ v1 ])
  | P v1 ->
      let v1 = vof_pattern v1 in
      OCaml.VSum ("P", [ v1 ])
  | Def v1 ->
      let v1 = vof_definition v1 in
      OCaml.VSum ("D", [ v1 ])
  | Dir v1 ->
      let v1 = vof_directive v1 in
      OCaml.VSum ("Di", [ v1 ])
  | Fld v1 ->
      let v1 = vof_field v1 in
      OCaml.VSum ("Fld", [ v1 ])
  | Di v1 ->
      let v1 = vof_dotted_name v1 in
      OCaml.VSum ("Dn", [ v1 ])
  | I v1 ->
      let v1 = vof_ident v1 in
      OCaml.VSum ("I", [ v1 ])
  | Pa v1 ->
      let v1 = vof_parameter v1 in
      OCaml.VSum ("Pa", [ v1 ])
  | Ce v1 ->
      let v1 = vof_catch_exn v1 in
      OCaml.VSum ("Ce", [ v1 ])
  | Ar v1 ->
      let v1 = vof_argument v1 in
      OCaml.VSum ("Ar", [ v1 ])
  | At v1 ->
      let v1 = vof_attribute v1 in
      OCaml.VSum ("At", [ v1 ])
  | XmlAt v1 ->
      let v1 = vof_xml_attribute v1 in
      OCaml.VSum ("XmlAt", [ v1 ])
  | Dk v1 ->
      let v1 = vof_definition_kind v1 in
      OCaml.VSum ("Dk", [ v1 ])
  | Pr v1 ->
      let v1 = vof_program v1 in
      OCaml.VSum ("Pr", [ v1 ])
  | Lbli v1 ->
      let v1 = vof_label_ident v1 in
      OCaml.VSum ("Lbli", [ v1 ])

and vof_raw_tree x =
  match x with
  | Token v ->
      let v = vof_wrap OCaml.vof_string v in
      OCaml.VSum ("Token", [ v ])
  | List v ->
      let v = (OCaml.vof_list vof_raw_tree) v in
      OCaml.VSum ("List", [ v ])
  | Tuple v ->
      let v = (OCaml.vof_list vof_raw_tree) v in
      OCaml.VSum ("Tuple", [ v ])
  | Case (v1, v2) ->
      let v1 = OCaml.vof_string v1 in
      let v2 = vof_raw_tree v2 in
      OCaml.VSum ("Case", [ v1; v2 ])
  | Option v ->
      let v = (OCaml.vof_option vof_raw_tree) v in
      OCaml.VSum ("Option", [ v ])
  | Any v ->
      let v = vof_any v in
      OCaml.VSum ("Any", [ v ])
